<?php
//
//  VictoryCMS - Content managment system and framework.
//  Copyright (C) 2009  Lewis Gunsch
//
//  This file is part of VictoryCMS.
//  
//  VictoryCMS is free software: you can redistribute it and/or modify
//  it under the terms of the GNU General Public License as published by
//  the Free Software Foundation, either version 3 of the License, or
//  (at your option) any later version.
//
//  VictoryCMS is distributed in the hope that it will be useful,
//  but WITHOUT ANY WARRANTY; without even the implied warranty of
//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//  GNU General Public License for more details.
//  
//  You should have received a copy of the GNU General Public License
//  along with VictoryCMS.  If not, see <http://www.gnu.org/licenses/>.

/**
 * VictoryCMS - UserManager
 * 
 * @license http://www.gnu.org/licenses/gpl.html
 * @author Lewis Gunsch
 * @package Deprecated
 */

/**
 * @deprecated This class will be removed in future versions!
 * 
 * This Class includes the functions necessary for displaying the
 * user management page of Victory church web site.
 *
 * @package Deprecated
 **/
class UserManager extends UserLogin implements DisplayablePage {

	/**
	 * Constants Used in this library.
	 **/
	// User Management Post Constants ////////////////////////////////////////////////
	const CURRENT_SELECTED_USER = "selected_user_id";
	const SELECTED_USER = "selected_user_id_post";
	const USER_POST = "username_post";
	const FIRST_NAME = "first_name";
	const LAST_NAME = "last_name";
	const EMAIL = "email";
	const PERMISSION = "permission";
	const PASSWORD = "password_update";
	const PASSWORD_VERIFY = "password_verify_update";
	const ACTION_BUTTON = "action_button";

	/*
	 * Determines if a user is updating his personal preferences or not.
	 */
	protected $personalUpdate;	

	/**
	 * This function returns the title of the DisplayablePage
	 * in a string.
	 *
	 * @return The title of the page
	 **/
	public function getTitle() {
		
		return "User Manager";
	}


	/**
	 * This function returns the name of the DisplayablePage
	 * in a string.
	 *
	 * @return The name of the page.
	 **/
	public function getName() {
		
		return "User Manager";
	}


	/**
	 * This function returns a short text description of a
	 * DisplayablePage in a string.
	 *
	 * @return A short description of the page
	 **/
	public function getDescription() {
		
		return "create, delete, and update user's information";
	}


	/**
	 * This function returns a comma seperated list
	 * of describing keywords in a string.
	 *
	 * @return A comma seperated keyword string
	 **/
	public function getKeywords() {
		return "";
	}


	/**
	 * This function returns the css style sheet
	 * in a string for the page.
	 *
	 * @return The css stylesheet for the page in a string
	 */
	public function getHeaderInfo() {
		
		$html = "";
		$html .= '<link href="http://www.victoryrock.org/members/vcotr1style.css" rel="stylesheet" type="text/css">';
		$html .= '<script src="http://www.victoryrock.org/members/vcotr1javascript.js" type="text/javascript"></script>';
		return $html;
	}


	/**
	 * This method returns the minimum necessary permissions
	 * needed to be able to view this page.
	 *
	 * @return Permission a permission object with permission set.
	 **/
	public function getPagePermissionLevel() {
		
		return new Permission("Team Admin");
	}


	/**
	 * This function returns a form of buttons for selecting an user.
	 * This requires the client to initialize sessions.
	 *
	 * @param action The page this function is used on.
	 *
	 * @return The html of the user chooser form.
	 **/
	protected function postUserChooserForm( $action ) {

		$html = "";
			
		$db = VcmsDBFactory::createVcmsDb();
		$query = sprintf( "SELECT user_name FROM User ORDER BY user_name" );
		$db->runQuery($query);
		// Build initial form
		$html .= "<form name='user_selector' method='POST' action='". $action ."'>\n";

		// Parse results into form
		$i = 0;
		while( $row = $db->fetchRow() ) {
			if ( $_SESSION[self::CURRENT_SELECTED_USER] != $row["user_name"] ) {
				$html .= "<input type='submit' name='selected_user_id_post'";
				$html .= " id='user". $i ."' class='chooser' style='width:150px;'";
				$html .= " onMouseOver='goLite(\"user".$i."\")' onMouseOut='goDim(\"user".$i."\")'";
				$html .= " value='". $row["user_name"] ."'><br>\n";
			} else {  // This event has been selected
				$html .= "<div class='selected' style='width:150px'";
				$html .= " align='center' name='selected'>". $row["user_name"] ."</div>\n";
			}
			$i++;
		}

		$html .= "</form>\n";

		// Close connection and return
		$db->cleanUp();
		return $html;
	}


	/**
	 * This function returns an user update form for the user id logged in the session.
	 * This function requires the cleint to initialize sessions.
	 *
	 * @param personal_update true if this is a personal update form and false if it
	 *        is used with the user chooser.
	 * @param action The page this function is used on
	 *
	 * @return The html of the user updater form.
	 **/
	protected function postUserUpdaterForm( $action, $is_personal_update = false ) {

		$html = "";
			
		$db = VcmsDBFactory::createVcmsDb();
		
		// set current user if a personal update
		if ($is_personal_update) {
			$this->personalUpdate = true;
			$_SESSION[self::CURRENT_SELECTED_USER] = $_SESSION[parent::USERNAME];
		} else {
			$this->personalUpdate = false;
		}

		// Get the user data
		$select = "SELECT user_name, first_name, last_name, email, permission, group_id, group_name";
		$from = "FROM User, Permission_Group";
		$where = sprintf( "WHERE user_name='%s' AND permission=group_id", $_SESSION[self::CURRENT_SELECTED_USER] );
		$query = sprintf( "%s %s %s", $select, $from, $where );
		$db->runQuery($query);
		
		// Build initial form
		$html .= "<form name='user_updater' method='POST' action='". $action ."'>\n";
		$html .= "<table name='user_updater_table' border='0'>\n";

		// Parse results into form
		$row = $db->fetchRow();
		
		// User id table row
		$html .= "<tr><td colspan='2'>\n<label class='updater' for='user_field'>User name:&nbsp;</label>";
		$html .= "<input class='updater' type='text' name='". self::USER_POST ."' id='user_field' size='45' maxlength='45'";
		if ( ! ($_POST[self::ACTION_BUTTON] == "New") ) {
			$html .= "readonly ";
		}
		$html .= "value='". $row["user_name"] ."'/>\n</td></tr>";

		// user first and last name table row
		$html .= "<tr><td>\n<label class='updater' for='first_field'>First:&nbsp;</label>";
		$html .= "<input class='updater' type='text' name='". self::FIRST_NAME ."' id='first_field' size='20'";
		$html .= " value='". $row["first_name"]. "'/>\n</td><td>\n";
		$html .= "<label class='updater' for='last_field'>Last:&nbsp;</label>";
		$html .= "<input class='updater' type='text' name='". self::LAST_NAME ."' id='last_field' size='20'";
		$html .= " value='". $row["last_name"] ."'/>\n</td></tr>";

		// email table row
		$html .= "<tr><td colspan='2'>\n<label class='updater' for='email_field'>Email:&nbsp;</label>";
		$html .= "<input class='updater' type='text' name='". self::EMAIL ."' id='email_field' size='45' maxlength='45'";
		$html .= " value='". $row["email"] ."'/>\n</td></tr>";

		if (! $this->personalUpdate) {
			// Permission id and name row
			$html .= "<tr><td colspan='2' align='left'>\n";
			$html .= "<label class='updater' for='group_id_field'>Permission level:&nbsp;</label>";
			$html .= $this->postGroupChooserField( $row["group_name"] );
			$html .= "</td></tr>";

			// This is a personal information update
		} else {
			// Permission level row
			$html .= "<tr><td colspan='2' align='left'>\n";
			$html .= "<label class='updater' for='group_id_field'>Permission level:&nbsp;</label>";
			$html .= "<input class='updater' id='group_id_field' name='".self::PERMISSION."' size='15' readonly ";
			$html .= "value='". $row["group_name"] ."'/>\n</td></tr>";

			// Password change rows
			$html .= "<tr><td colspan='2'>\n<label class='updater' for='password_field'>New Password:&nbsp;</label>";
			$html .= "<input class='updater' type='password' name='". self::PASSWORD ."' id='password_field' size='45' maxlength='45'";
			$html .= " value=''/>\n</td></tr>";

		 	// Verify password change row
			$html .= "<tr><td colspan='2'>\n<label class='updater' for='verify_field'>Verify:&nbsp;</label>";
			$html .= "<input class='updater' type='password' name='". self::PASSWORD_VERIFY ."' id='verify_field' size='45' maxlength='45'";
			$html .= " value=''/>\n</td></tr>";
		}

		$html .= "<tr><td colspan='2' align='center'>\n";

		// Submitt button
		if ( $_POST[self::ACTION_BUTTON] == "New" ) {
			$html .= "<input id='action1' type='submit' name='". self::ACTION_BUTTON ."' value='Insert'";
			$html .= " onMouseOver='goLite(\"action1\")' onMouseOut='goDim(\"action1\")'";
			$html .= "class='chooser' style='width: 50px;' />\n";
		} else {
			$html .= "<input id='action2' type='submit' name='". self::ACTION_BUTTON ."' value='Update'";
			$html .= " onMouseOver='goLite(\"action2\")' onMouseOut='goDim(\"action2\")'";
			if ($this->personalUpdate) {
				$html .= " onClick='return validatePassword();'";
			}
			$html .= " class='chooser' style='width: 50px;' />\n";

			// Only if this is not a personal update
			if ( !$this->personalUpdate) {
				$html .= "<input id='action3' type='submit' name='". self::ACTION_BUTTON ."' value='New'";
				$html .= " onMouseOver='goLite(\"action3\")' onMouseOut='goDim(\"action3\")'";
				$html .= " class='chooser' style='width: 50px;' />\n";
				$html .= "<input id='action4' type='submit' name='". self::ACTION_BUTTON ."' value='Delete'";
				$html .= " onMouseOver='goLite(\"action4\")' onMouseOut='goDim(\"action4\")'";
				$html .= " onClick='return confirm(\"Delete ?\");' class='chooser' style='width: 50px;' />\n";
				$html .= "<input id='action5' type='submit' name='". self::ACTION_BUTTON ."' value='Reset Password'";
				$html .= " onMouseOver='goLite(\"action5\")' onMouseOut='goDim(\"action5\")'";
				$html .= " onClick='return confirm(\"Reset Password ?\");' class='chooser' style='width: 100px;' />\n";
			}
		}

		$html .= "</td></tr>";
		$html .= "</table></form>\n";

		// Close connection and return
		$db->cleanUp();
		return $html;
	}


	/**
	 * This function returns a drop down box for the user to select
	 * a permission level for updating or creating a new user.
	 * This input field's name is "permission".
	 *
	 * @param selected The currently selected permission group level (group_name column).
	 *
	 * @return The html of the drop down box.
	 **/
	protected function postGroupChooserField( $selected ) {

		$html = "";

		// Connect and execute query
		$db = VcmsDBFactory::createVcmsDb();
		
		// Get the user data
		$query = "SELECT group_id, group_name FROM Permission_Group ORDER BY group_id DESC";
		$db->runQuery($query);
		
		$html .= "<select name='". self::PERMISSION ."'>\n";
		while ( $row = $db->fetchRow() ) {
			$html .= "\t<option ";
			if ( $row["group_name"] == $selected ) {
				$html .= "selected ";
			}
			$html .= "value='". $row["group_id"] ." ". $row["group_name"] ."'>";
			$html .= "". $row["group_name"] ."</option>\n";
		}
		$db->cleanUp();
		$html .= "</select>\n";
		return $html;
	}


	/**
	 * This function handles the actions for the action buttons for the user update form.
	 **/
	protected function userButtonActionHandler() {

		// Connect to database
		$db = VcmsDBFactory::createVcmsDb();
		
		// Set currently selected user
		if (! empty($_POST[self::SELECTED_USER]) ) {
			$selected_user = $_POST[self::SELECTED_USER];
			$_SESSION[self::CURRENT_SELECTED_USER] = $selected_user;
			unset( $_POST[self::SELECTED_USER] );
		}

		// post insert page
		if ( $_POST[self::ACTION_BUTTON] == "New" ) {

			// post new form
			unset( $_SESSION[self::CURRENT_SELECTED_USER] );

			// Insert new user
		} elseif ( $_POST[self::ACTION_BUTTON] == "Insert" ) {

			// Do not create a user for a spammer email
			$to = $this->spamcheck( $_POST[self::EMAIL] );
			if ( $to == TRUE) {

				// Get the data
				$user = trim( $_POST[self::USER_POST] );
				$first_name = trim( $_POST[self::FIRST_NAME] );
				$last_name = trim( $_POST[self::LAST_NAME] );
				$email = trim( $_POST[self::EMAIL] );
				$permission = trim( $_POST[self::PERMISSION] );

				// Check the data!
				if ( empty( $user) || empty( $email ) ) {
					die( "User Name and Email must be set!" );
				}

				// Check Email Uniqueness First!
				$this->verifyEmailUnique( $action );
					
				// Check username uniqueness
				$this->verifyUserNameUnique( $action );

				// get permission level
				sscanf( $_POST[self::PERMISSION], "%d", $permission_level );

				// get new password and encode it
				$password = $this->createRandomPassword();
				
				$encoded_password = convert_uuencode( $password );

				// Insert user
				$insert = "INSERT INTO User (user_name, first_name, last_name, email, permission, password)";
				$values = sprintf( "VALUES ( '%s', '%s', '%s', '%s', '%d', \"%s\" )",
				$user, $first_name, $last_name, $email, $permission_level, $encoded_password );
				$query = sprintf( "%s %s", $insert, $values );
				$db->runQuery($query);

				// Send password and username to new User
				$this->sendPasswordEmail( $password );
			}

			// set current user id to new one
			$_SESSION[self::CURRENT_SELECTED_USER] = $_POST[self::USER_POST];

			// update user
		} elseif ( $_POST[self::ACTION_BUTTON] == "Update" ) {

			// Get the data
			$first_name = trim( $_POST[self::FIRST_NAME] );
			$last_name = trim( $_POST[self::LAST_NAME] );
			$email = trim( $_POST[self::EMAIL] );
			if (! $this->personalUpdate) {
				$permissionString = trim( $_POST[self::PERMISSION] );
				sscanf( $permissionString, "%d", & $permission);
				if (!is_numeric($permission)) {
					throw new Exception("Permission level $permission is not a number.");
				}
			}
			
			// Make sure a user is selected 
			if ( empty( $_SESSION[self::CURRENT_SELECTED_USER] ) ) {
				die( "You cannot edit a user when there are none selected!".
				" Please go <a href='". $action ."'>back</a> and choose one."  );
			}
			// Check the data!
			if ( empty( $email ) ) {
				die( "Email must be set!" );
			}

			// Check Email Uniqueness First!
			$this->verifyEmailUnique( $action );

			// Update user information
			$update = "UPDATE User";
			
			// never update permission if it is a preferences update!
			if ($this->personalUpdate) {
				$set = sprintf( "SET first_name='%s', last_name='%s', email='%s'",
				$first_name, $last_name, $email );	
			} else {
				$set = sprintf( "SET first_name='%s', last_name='%s', email='%s', permission=%d",
				$first_name, $last_name, $email, $permission );
			}
			
			$where = sprintf( "WHERE user_name='%s'", $_SESSION[self::CURRENT_SELECTED_USER] );
			$query = sprintf( "%s %s %s", $update, $set, $where );
			$db->runQuery($query);
			
			// Update user password if it was set
			if ( !empty( $_POST[self::PASSWORD] ) && !empty( $_POST[self::PASSWORD_VERIFY] ) ) {
					
				$encoded_password = convert_uuencode( $_POST[self::PASSWORD] );
				$query = sprintf( "UPDATE User SET password=\"%s\" WHERE user_name='%s' ",
				$encoded_password, $_SESSION[self::CURRENT_SELECTED_USER] );
				$db->runQuery($query);
				
				// Send password and username to User
				$this->sendPasswordEmail( $_POST[self::PASSWORD] );
			}

			// clear personal update
			$this->personalUpdate = false;
			
			// delete user
		} elseif ( $_POST[self::ACTION_BUTTON] == "Delete" ) {

			// Make sure a user is selected
			if ( empty( $_SESSION[self::CURRENT_SELECTED_USER] ) ) {
				die( "You cannot edit a user when there are none selected!".
				" Please go <a href='". $action ."'>back</a> and choose one." );
			}
			// Delete user
			$query = sprintf( "DELETE FROM User WHERE user_name='%s'", $_SESSION[self::CURRENT_SELECTED_USER] );
			$db->runQuery($query);
			
			// reset current event id
			unset( $_SESSION[CURRENT_EVENT] );

			// Reset user password
		} elseif ( $_POST[self::ACTION_BUTTON] == "Reset Password" ) {

			// Make sure a user is selected
			if ( empty( $_SESSION[self::CURRENT_SELECTED_USER] ) ) {
				die( "You cannot edit a user when there are none selected!".
				" Please go <a href='". $action ."'>back</a> and choose one."  );
			}
			// get new password and encode it
			$password = $this->createRandomPassword();
			$encoded_password = convert_uuencode( $password );

			// Reset user password
			$update = "UPDATE User";
			$set = sprintf( "SET password=\"%s\"", $encoded_password );
			$where = sprintf( "WHERE user_name='%s'", $_SESSION[self::CURRENT_SELECTED_USER] );
			$query = sprintf( "%s %s %s", $update, $set, $where );
			$db->runQuery($query);
			
			// Send new password to User
			$this->sendPasswordEmail( $password );
		}

		// Close connection and return
		$db->cleanUp();
		
		return;
	}


	/**
	 * This function returns the html content of the page in a string.
	 * The content should not contain the template, just the page container
	 * content. The current page parameter should be set to the relative page
	 * path calling this function.
	 *
	 * @param currentPage The current relative page path calling this function.
	 *
	 * @return A string containing the html page content
	 **/
	public function renderPage( $currentPage ) {
		
		$html = "";
		$html .= "<h3 align='center'>User Management</h3>\n";
		$html .= "<table class='gray' id='user_chooser_updater' border='1' align='center' cellpadding='3' ";
		$html .= "cellspacing='0' class='user_update_table'>\n";
		$html .= "<tr class='gray'><th  class='gray'align='center'>&nbsp;Users&nbsp;</th>";
		$html .= "<th class='gray' align='center'>&nbsp;View-Update&nbsp;</th></tr>\n";
		$html .= "<tr class='gray'><td class='gray'>\n";
		$html .= $this->postUserChooserForm( $currentPage );
		$html .= "</td><td>\n";
		$html .= $this->postUserUpdaterForm( $currentPage );
		$html .= "</td></tr>";
		$html .= "</table>\n<hr>";
		return $html;
	}


	/**
	 * This method is run before the page is displayed and
	 * before any content is retrieved. This method is meant
	 * to let the page do any necessary preprocessing.
	 *
	 **/
	public function pagePreProcess() {
		
		$this->userButtonActionHandler();
	}


	/**
	 *  This function verifies that the email field of the
	 *  form is unique. If it is not unique the function
	 *  dies and requests the user to go back.
	 *
	 *	@TODO: maybe use filter_var to validate email 
	 *  @param conn The connection to the database being used.
	 *  @param action The page this function is used on
	 **/
	protected function verifyEmailUnique( $action ) {
		
		$db = VcmsDBFactory::createVcmsDb();
		$select = sprintf( "SELECT COUNT(email) AS duplicates FROM User" );
		$where = sprintf( "WHERE email='%s' AND user_name<>'%s'",
		$_POST[self::EMAIL], $_SESSION[self::CURRENT_SELECTED_USER] );
		$query = sprintf( "%s %s", $select, $where );
		$db->runQuery($query);
		$row = $db->fetchRow();
		
		if ( $row["duplicates"] > 0 ) {
			die( "You entered an email that is alread in use.".
				" Please go <a href='". $action ."'>back</a> and enter a different one." );
		} else {
			return;
		}
		$db->cleanUp();
	}


	/**
	 *  This function verifies that the username field of the
	 *  form is unique when inserting. If it is not unique the function
	 *  dies and requests the user to go back.
	 *
	 *  @param conn The connection to the database being used.
	 *  @param action The page this function is used on
	 **/
	protected function verifyUserNameUnique( $action ) {

		$db = VcmsDBFactory::createVcmsDb();
		$select = sprintf( "SELECT COUNT(user_name) AS duplicates FROM User" );
		$where = sprintf( "WHERE user_name='%s'", trim( $_POST[self::USER_POST] ) );
		$query = sprintf( "%s %s", $select, $where );
		$db->runQuery($query);
		$row = $db->fetchRow();
		
		if ( $row["duplicates"] > 0 ) {
			die( "You entered an username that is alread in use.".
				" Please go <a href='". $action ."'>back</a> and enter a different one." );
		} else {
			return;
		}
	}


	/**
	 * This function sends the password and username of a new user
	 * to their inbox. This does not check the  email post for
	 * spammer email's. That should be done elsewhere.
	 *
	 * @param password The password to be emailed.
	 */
	protected function sendPasswordEmail( $password ) {

		$subject = "Your username and password from Victory Church on the Rock Edmonton West";
		
		$to = $_POST[self::EMAIL];
		$from = "dale@victoryrock.org";
		
		$message = "
		<html>
		<head>
			<title>Your username and password from Victory Church on the Rock Edmonton West</title>
		</head>
		<body>
			<p>
				<strong>Welcome to the Victory Church on the Rock members portal.</strong>
			</p>
			<p>
				Please login at 
				<a href='http://www.victoryrock.org/members'>http://www.victoryrock.org/members</a>
				with the following user name and password and click on MY ACCOUNT to change your password:
			</p>
			<ul>
				<li>User name: ". $_POST[self::USER_POST] ."</li>
				<li>Password:  $password </li>
			</ul>
			<p>
				<em>Victory Church on the Rock Web Administration</em>
			</p>
		</body>
		</html>
		";
		
		// Always set content-type when sending HTML email
		$headers = "MIME-Version: 1.0" . "\r\n";
		$headers .= "Content-type:text/html;charset=iso-8859-1" . "\r\n";
		$headers .= 'From: <'.$from.'>' . "\r\n";
		$headers .= 'Cc: ' . "\r\n";

		mail($to,$subject,$message,$headers);
		
		
		return;
	}


	/**
	 * This function creates a random password 8 characters long and
	 * returns it as a string.
	 * The letter l (lowercase L) and the number 1
	 * have been removed, as they can be mistaken
	 * for each other.
	 *
	 * From: "http://www.totallyphp.co.uk/code/create_a_random_password.htm"
	 */
	protected function createRandomPassword() {

		$chars = "abcdefghijkmnopqrstuvwxyzABCDEFGHIJKMNOPQRSTUVWXYZ023456789";
		srand((double)microtime()*1000000);
		$i = 0;
		$pass = "" ;

		while ($i <= 7) {
			$num = rand() % 58;
			$tmp = substr($chars, $num, 1);
			$pass = $pass . $tmp;
			$i++;
		}

		return $pass;
	}


	/**
	 * This function filters the email field to prevent spamming through
	 * missuse of the email field. It returns false if the field is missused
	 * and true if not.
	 *
	 * @return True if email passes and false if not.
	 **/
	protected function spamcheck( $field ) {
			
		$field = filter_var($field, FILTER_SANITIZE_EMAIL);
		if( filter_var( $field, FILTER_VALIDATE_EMAIL ) ) {
			return TRUE;
		} else {
			return FALSE;
		}
	}

}
?>